from session import Session
import logging
import json
import session
import uuid
from crypt import Crypt

class MessageHandler():
    
    def checkData(self, data, addr):
        logging.debug('Checking data sent from ' + addr[0] + ':' + str(addr[1]))
        if self.validForJSON(data):
            logging.debug('Message: ' + str(data) + ' ...')
            data = json.loads(str(data, 'utf8'))
            if self.hasFunction(data):
                if self.hasNonIDfunction(data):
                    logging.debug('Everything seems well.')
                    return True
                elif self.hasSessionID(data) and self.sessionCreated(data, addr):
                    logging.debug('Everything seems well.')
                    return True
                logging.debug('Execution of ' + data['function'] + ' not allowed without creating a session.')
        else:
            logging.debug('Trying to decode...')
            data = self.crypted(data, addr)
            if data != None:
                if self.validForJSON(data):
                    logging.debug('Message: ' + str(data) + ' ...')
                    data = json.loads(str(data, 'utf8'))
                    if self.hasFunction(data):
                        if self.hasNonIDfunction(data):
                            logging.debug('Everything seems well.')
                            return True
                        elif self.hasSessionID(data) and self.sessionCreated(data, addr):
                            logging.debug('Everything seems well.')
                            return True
                        logging.debug('Execution of ' + data['function'] + ' not allowed without creating a session.')
        return False
    
    def validForJSON(self, data):
        try:
            json.loads(str(data, 'utf8'))
        except Exception as msg:
            logging.error("Not valid for JSON. Err msg: " + str(msg))
            return False
        return True
    
    def crypted(self, data, addr):
        decrypted = None
        ID = Session().getID(addr[0])
        if ID != None:
            try:
                key = session.Session().getID(addr[0])
                key = uuid.UUID(key)
                key = key.bytes
                decrypted = Crypt().decrypt(data, key)
            except Exception as msg:
                return None
        else:
            return None
        return decrypted
        
    def hasFunction(self, data):
        try:
            data['function']
        except Exception:
            logging.debug('No function specified in request.')
            return False
        return True
    
    def hasSessionID(self, data):
        try:
            data['sessionID']
        except Exception:
            logging.debug('No ID sent.')
            return False
        return True
    
    def sessionCreated(self, data, addr):
        if Session().sessionExists(data['sessionID'], addr[0]):
            return True
        logging.debug('Session is not active.')
        return False
    
    def hasNonIDfunction(self, data):
        if data['function'] == 'getHostName' or data['function'] == 'connect':
            return True
        return False